#include "Precomp.h"
#if (defined(_MSC_VER)&& defined(_M_IX86))
//#include "PostMortemDebug.h"
#define VC_EXTRALEAN
#include <windows.h>
#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>

  LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(
    LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
  {
    return NULL;
  }

  BOOL PreventSetUnhandledExceptionFilter()
  {
    HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
    if (hKernel32==NULL) return FALSE;
    void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
    if(pOrgEntry==NULL) return FALSE;
    unsigned char newJump[ 100 ];
    DWORD dwOrgEntryAddr = (DWORD) pOrgEntry;
    dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far
    void *pNewFunc = &MyDummySetUnhandledExceptionFilter;
    DWORD dwNewEntryAddr = (DWORD) pNewFunc;
    DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;

    newJump[ 0 ] = 0xE9;  // JMP absolute
    memcpy(&newJump[ 1 ], &dwRelativeAddr, sizeof(pNewFunc));
    SIZE_T bytesWritten;
    BOOL bRet = WriteProcessMemory(GetCurrentProcess(),
      pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);
    return bRet;
  }

long WINAPI GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
{
	// Open the file 
	HANDLE hFile = CreateFile( _T("MiniDump.dmp"), GENERIC_READ | GENERIC_WRITE, 
		0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 
	if( ( hFile != NULL ) && ( hFile != INVALID_HANDLE_VALUE ) ) 
	{
		// Create the minidump
		MINIDUMP_EXCEPTION_INFORMATION mdei; 

		mdei.ThreadId           = GetCurrentThreadId(); 
		mdei.ExceptionPointers  = pExceptionPointers; 
		mdei.ClientPointers     = FALSE; 

		MINIDUMP_CALLBACK_INFORMATION mci; 

		mci.CallbackRoutine     = 0; 
		mci.CallbackParam       = 0; 

		MINIDUMP_TYPE mdt       = (MINIDUMP_TYPE)(
			MiniDumpWithDataSegs |
			MiniDumpWithIndirectlyReferencedMemory | 
			MiniDumpScanMemory); 

		BOOL rv = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), 
			hFile, mdt, (pExceptionPointers != 0) ? &mdei : 0, 0, &mci ); 
		if( !rv ) 
			wprintf( _T("MiniDumpWriteDump failed. Error: %u \n"), GetLastError() ); 
		else 
			wprintf( _T("Minidump created.\n") ); 
		// Close the file 
		CloseHandle( hFile ); 
	}
	else 
	{
		wprintf( _T("CreateFile failed. Error: %u \n"), GetLastError() ); 
	}

	MessageBoxA(0,"Error occured, please send the Minidump.dmp file to the developer","Error",MB_ICONERROR);
    return EXCEPTION_EXECUTE_HANDLER;
}

void _enableCrashHandler()
{
	SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) GenerateDump);
	PreventSetUnhandledExceptionFilter();
}

#endif